/**
 * 日志工具
 * 提供统一的日志记录功能
 */

// 日志级别枚举
const LOG_LEVEL = {
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3,
  NONE: 4
};

// 日志类型标签
const LOG_TAGS = {
  [LOG_LEVEL.DEBUG]: '[DEBUG]',
  [LOG_LEVEL.INFO]: '[INFO]',
  [LOG_LEVEL.WARN]: '[WARN]',
  [LOG_LEVEL.ERROR]: '[ERROR]'
};

// 最大日志缓存数量
const MAX_LOG_CACHE = 200;

/**
 * 日志记录器类
 */
class Logger {
  constructor() {
    // 当前日志级别
    this.level = LOG_LEVEL.INFO;
    
    // 是否启用本地存储
    this.enableStorage = false;
    
    // 日志缓存
    this.logCache = [];
    
    // 网络日志缓存
    this.networkLogCache = [];
    
    // 日志存储键
    this.storageKey = 'app_logs';
    
    // 网络日志存储键
    this.networkStorageKey = 'network_logs';
    
    // 日志分组计数器
    this.groupCount = 0;
    
    // 是否显示时间戳
    this.showTimestamp = true;
  }
  
  /**
   * 设置日志级别
   * @param {number} level 日志级别
   */
  setLevel(level) {
    if (level >= LOG_LEVEL.DEBUG && level <= LOG_LEVEL.NONE) {
      this.level = level;
    }
  }
  
  /**
   * 启用本地存储
   * @param {boolean} enable 是否启用
   */
  setStorageEnabled(enable) {
    this.enableStorage = enable === true;
  }
  
  /**
   * 记录调试日志
   * @param {string} message 日志消息
   * @param {...any} args 其他参数
   */
  debug(message, ...args) {
    this._log(LOG_LEVEL.DEBUG, message, args);
  }
  
  /**
   * 记录信息日志
   * @param {string} message 日志消息
   * @param {...any} args 其他参数
   */
  info(message, ...args) {
    this._log(LOG_LEVEL.INFO, message, args);
  }
  
  /**
   * 记录警告日志
   * @param {string} message 日志消息
   * @param {...any} args 其他参数
   */
  warn(message, ...args) {
    this._log(LOG_LEVEL.WARN, message, args);
  }
  
  /**
   * 记录错误日志
   * @param {string} message 日志消息
   * @param {...any} args 其他参数
   */
  error(message, ...args) {
    this._log(LOG_LEVEL.ERROR, message, args);
  }
  
  /**
   * 记录网络日志
   * @param {Object} logData 网络日志数据
   * @param {string} logData.type 日志类型（request/response/error）
   * @param {string} logData.url 请求URL
   * @param {string} logData.method 请求方法
   * @param {Object} logData.data 请求或响应数据
   * @param {number} logData.statusCode 响应状态码
   * @param {Object} logData.error 错误信息
   */
  network(logData) {
    // 如果未启用网络日志，跳过
    if (this.level > LOG_LEVEL.DEBUG) return;
    
    // 添加时间戳
    const logEntry = {
      ...logData,
      timestamp: new Date().toISOString()
    };
    
    // 添加到网络日志缓存
    this.networkLogCache.push(logEntry);
    
    // 限制缓存大小
    if (this.networkLogCache.length > MAX_LOG_CACHE) {
      this.networkLogCache.shift();
    }
    
    // 如果启用了存储，保存网络日志
    if (this.enableStorage) {
      this._saveNetworkLogs();
    }
    
    // 控制台输出
    const typeTag = `[NETWORK:${logData.type.toUpperCase()}]`;
    const url = logData.url || '';
    const method = logData.method || '';
    
    if (logData.type === 'error') {
      console.error(typeTag, `${method} ${url}`, logData.error);
    } else {
      console.log(typeTag, `${method} ${url}`, logData.data || '');
    }
  }
  
  /**
   * 内部日志记录方法
   * @param {number} level 日志级别
   * @param {string} message 日志消息
   * @param {Array} args 其他参数
   * @private
   */
  _log(level, message, args) {
    // 检查日志级别
    if (level < this.level) return;
    
    // 生成日志前缀
    const tag = LOG_TAGS[level] || '';
    const timestamp = this.showTimestamp ? `[${new Date().toISOString()}]` : '';
    const prefix = `${tag}${timestamp}`;
    
    // 构建日志条目
    const logEntry = {
      level,
      message,
      args: args || [],
      timestamp: new Date().toISOString()
    };
    
    // 添加到缓存
    this.logCache.push(logEntry);
    
    // 限制缓存大小
    if (this.logCache.length > MAX_LOG_CACHE) {
      this.logCache.shift();
    }
    
    // 如果启用了存储，保存日志
    if (this.enableStorage) {
      this._saveLogs();
    }
    
    // 根据日志级别选择控制台输出方法
    switch (level) {
      case LOG_LEVEL.DEBUG:
        console.log(prefix, message, ...args);
        break;
      case LOG_LEVEL.INFO:
        console.info(prefix, message, ...args);
        break;
      case LOG_LEVEL.WARN:
        console.warn(prefix, message, ...args);
        break;
      case LOG_LEVEL.ERROR:
        console.error(prefix, message, ...args);
        break;
    }
  }
  
  /**
   * 保存日志到本地存储
   * @private
   */
  _saveLogs() {
    try {
      wx.setStorage({
        key: this.storageKey,
        data: JSON.stringify(this.logCache),
      });
    } catch (e) {
      console.error('保存日志失败', e);
    }
  }
  
  /**
   * 保存网络日志到本地存储
   * @private
   */
  _saveNetworkLogs() {
    try {
      wx.setStorage({
        key: this.networkStorageKey,
        data: JSON.stringify(this.networkLogCache),
      });
    } catch (e) {
      console.error('保存网络日志失败', e);
    }
  }
  
  /**
   * 获取日志
   * @returns {Array} 日志数组
   */
  getLogs() {
    return [...this.logCache];
  }
  
  /**
   * 获取网络日志
   * @returns {Array} 网络日志数组
   */
  getNetworkLogs() {
    return [...this.networkLogCache];
  }
  
  /**
   * 从本地存储恢复日志
   */
  restoreLogs() {
    try {
      const logs = wx.getStorageSync(this.storageKey);
      if (logs) {
        this.logCache = JSON.parse(logs);
      }
      
      const networkLogs = wx.getStorageSync(this.networkStorageKey);
      if (networkLogs) {
        this.networkLogCache = JSON.parse(networkLogs);
      }
    } catch (e) {
      console.error('恢复日志失败', e);
    }
  }
  
  /**
   * 清除日志
   */
  clearLogs() {
    this.logCache = [];
    
    if (this.enableStorage) {
      try {
        wx.removeStorageSync(this.storageKey);
      } catch (e) {
        console.error('清除日志存储失败', e);
      }
    }
  }
  
  /**
   * 清除网络日志
   */
  clearNetworkLogs() {
    this.networkLogCache = [];
    
    if (this.enableStorage) {
      try {
        wx.removeStorageSync(this.networkStorageKey);
      } catch (e) {
        console.error('清除网络日志存储失败', e);
      }
    }
  }
  
  /**
   * 开始分组日志
   * @param {string} label 分组标签
   */
  group(label) {
    if (typeof console.group === 'function') {
      console.group(label);
    } else {
      console.log(`=== 分组开始: ${label} ===`);
    }
    this.groupCount++;
  }
  
  /**
   * 结束分组日志
   */
  groupEnd() {
    if (this.groupCount > 0) {
      if (typeof console.groupEnd === 'function') {
        console.groupEnd();
      } else {
        console.log('=== 分组结束 ===');
      }
      this.groupCount--;
    }
  }
  
  /**
   * 将对象转为JSON字符串
   * @param {Object} obj 要转换的对象
   * @returns {string} JSON字符串
   */
  stringifyObject(obj) {
    try {
      return JSON.stringify(obj, null, 2);
    } catch (e) {
      return String(obj);
    }
  }
}

// 导出日志级别枚举
Logger.LOG_LEVEL = LOG_LEVEL;

// 创建单例
const logger = new Logger();

// 导出单例
module.exports = {
  logger,
  LOG_LEVEL
};
